import {
  definePage,
  getHistory,
  OType,
  udp,
  useAsyncEffect,
  Layout,
  getCurrentWindow,
  openAttachment,
  type PromiseType,
  $ImpSdk
} from '@cscec/udp-ui';
import React, { useMemo } from 'react';
import { ToastComponent, render as renderAmis } from 'amis';
import { Empty } from 'antd';
import { BaseCustom } from '../BaseCustom';
import { commonConfig, QueryParamName } from '../constVar';
import { initPage, PageContext, usePageCtx } from '../context';
import type { IDetailPage, IDetailPageRef, IPageFunction } from '../interface';
import { useDetail } from '../useUILayout';
import initDetailController from './controller';
import detailModel from './store';
import { getAmisEnv } from '@/components/editor/util';
import { getRequestByConfig } from '../service';

function formatValue(values: any) {
  values = udp.deepCopy(values);
  Object.keys(values).forEach((key) => {
    if (udp.isArray(values[key])) {
      values[key] = values[key].map((item) => item.value ?? item).join();
    } else if (udp.isObject(values[key]) && values[key].hasOwnProperty('value')) {
      values[key] = values[key].value;
    }
  });
  return values;
}

function PageDetailView() {
  const { page, uiInfo, refreshKey, capacity } = usePageCtx<IDetailPage>();
  const { [QueryParamName.id]: urlId, [QueryParamName.oType]: type, ...impParams } = getHistory().location.query || {};
  const urlRoot = page.getMicroServiceName();

  const env = useMemo(() => getAmisEnv('render', { urlRoot }), [urlRoot]);

  const { initState, masterTableName } = useDetail(page.getPublicProperty());
  const { data: stateData } = page.getDvaState();
  const { oType } = page;

  useAsyncEffect(async () => {
    if(capacity?.bizFlowFlag == 1) {
      const cacheKey = udp.getQueryValue('cacheKey');
      const flowCode = udp.getQueryValue('flowCode');
      if(flowCode){
        if (initState[masterTableName]) {
          initState[masterTableName].flowCode = flowCode;
        }
      }
      if(cacheKey) {
        await $ImpSdk.getPushBillData({cacheKey, autoFill : true})
      }
    }
    
  
    await page.umiDispatch({
      type: 'loadData',
      payload: {
        page,
        masterTableName,
        initState,
        impParams
      }
    });
  }, [refreshKey]);

  return (
    <Layout loading={page.props.loading.global} height="100%">
      <ToastComponent key="toast" position="top-right" />
      {uiInfo ? (
        renderAmis(
          {
            type: 'service',
            data: { oType, stateData, uiInfo, test123: 'test123' },
            body: uiInfo
          },
          {
            scopeRef(amisScoped: any) {
              getCurrentWindow().amisScoped = amisScoped;
            },
            style: { height: '100%' },
            className: 'lowcode-view-root',
            extraData: {
              //会传递给所有子孙组件
              capacity,
              page,
            }
          },
          env
        )
      ) : (
        <Empty style={{ marginTop: 100 }} />
      )}
    </Layout>
  );
}

/**
 * 自定义明细页面
 * @param busType
 * @param nextRoute
 * @constructor
 */
function CustomFormDetail({ busType: defaultBusType, nextRoute = '/customform/list' }: IPageFunction) {
  const { busType } = initPage(defaultBusType);
  const InnerPage = useMemo(
    () =>
      definePage({
        ...commonConfig,
        model: detailModel({ busType }),
        component: class extends BaseCustom<IDetailPageRef, IDetailPage> {
          private oType: OType;

          private Id: string;

          asrSessionGuid: string | undefined;

          constructor(props: any) {
            super(props, nextRoute, false);
            initDetailController(this as any);
            this.oType = udp.getQueryValue(QueryParamName.oType);
            this.Id = udp.getQueryValue(QueryParamName.id);
          }

          async closeCheck() {
            const submitData = this.getSubmitData().data;
            const isChanged = Object.keys(submitData).some((k) => submitData[k].isChanged);
            if (isChanged) {
              return {};
            }
            return true;
          }

          async validData() {
            const { data } = this.getDvaState();
            const validResult: PromiseType<boolean>[] = [];
            Object.keys(data).forEach((tableName: string) => {
              const api = this.getCmpApi(tableName);
              if (api?.validData) {
                validResult.push(api.validData());
              }
            });
            if (validResult.length > 0) {
              try {
                const ret = await Promise.all(validResult);
                return ret.every((r) => r === true);
              } catch {
                return false;
              }
            }
            return true;
          }

          getAllData() {
            return this.getDvaState().data;
          }

          getMainForm() {
            return this.getDvaState().data[this.getPublicProperty().masterTableName];
          }

          getSubmitData() {
            const { masterTableName } = this.getPublicProperty();
            const stateData = this.getAllData();
            // console.log('[debug] stateData:', stateData);
            const busKey = this.getBusKey();
            // 没有强制调用form或者table的api获取状态，是因为tab页的组件可能没有渲染，导致无法获取组件实例
            const data = Object.keys(stateData).reduce((p, c) => {
              // console.log('[debug] getSubmitData:', c, this.getCmpApi(c));
              if (c === masterTableName) {
                // 主表数据格式转换
                this._setQueryValue(stateData[c]);  //主表添加查询参数
                const opt = stateData[c][busKey] ? 'modifiedRow' : 'newRow';
                return {
                  ...p,
                  [c]: {
                    form: {
                      key: busKey,
                      [opt]: formatValue(stateData[c])
                    }
                  }
                };
              }
              // 子表
              const changeData = this.getCmpApi(c)?.getChange?.({ simple: false });
              return { ...p, [c]: changeData };
            }, {});
            return {
              data,
              bizCode: this.busType
            };
          }

          refreshData() {
            this.state.providerValue.forceUpdate();
          }

          _setQueryValue(initData){
              const flowCode = udp.getQueryValue('flowCode');
              const uiSchemeId = udp.getQueryValue('ui_scheme_id');
              flowCode && (initData.flowCode = flowCode);
              uiSchemeId && (initData.uiSchemeId = uiSchemeId);
          }

          async saveData() {
            if (!(await this.validData())) {
              return false;
            }
            const submitData = this.getSubmitData();
            // console.log('[debug] submitData:', submitData);
            // return false;
            // 获取内置钩子
            const hooks = await this.createHooks();
            const hookReturn = await hooks.transferSaveParams?.(submitData);
            if (hookReturn?.cancel) {
              udp.debug('transferSaveParams 返回false，取消保存！');
              return false;
            }

            const uiInfo = this.getLayout();
            const localRequest = getRequestByConfig(
              this.getMicroServiceName(),
              uiInfo.requestSave || {
                method: 'post',
                url: '/customForm/customPC/save'
              }
            );
            const result = await localRequest({
              data: {
                asrSessionGuid: this.asrSessionGuid,
                ...submitData,
                ...hookReturn?.params
              }
            });
            if (result.code === 0) {
              const resData = udp.isArray(result.data) ? result.data[0] : result.data;
              this.Id = resData.key;
              if (this.oType === OType.Add) {
                this.oType = OType.Edit;
              }
              this.refreshData();
              udp.refreshList(this.busType, {});

              //业务流特殊处理
              if(this.getCapacity()?.bizFlowFlag == 1) {
                await $ImpSdk.closeTaskByTaskId( {taskId: udp.getQueryValue( 'taskId')});
              }

              return resData.key;
            }
            await udp.alert(result.message);
            return false;
          }

          //引用数据来源
          async quoteSrc() {
            const flowCode = udp.getQueryValue('flowCode');
            const masterTableName = this.getPublicProperty().masterTableName;
            if (flowCode) {
              await $ImpSdk.citeSource({
                autoFill: true,
                bizCode: busType,
                tableName: masterTableName,
                flowCode,
                busData: this.getMainForm()
              });
              return;
            }
            // 引用来源,获取业务流
            const [rc, result] = await $ImpSdk.flowHelp({
              bizCode: busType,
              bizType: 0
            });

            if (rc) {
              // 有流程数据就获取引用来源
              const params = {
                autoFill: true,
                bizCode: busType,
                tableName: masterTableName,
                flowCode: result.flowCode,
                busData: this.getMainForm()
              };
              await $ImpSdk.citeSource(params);
            } else {
              // 没有流程数据就提示
              udp.alert('没有匹配的流程数据');
            }
          }

          async openAttachment() {
            const { masterTableName } = this.getPublicProperty();
            const asrSessionGuid = this.asrSessionGuid || this.getMainForm()?.sysToolbarColumn;
            const result: any = await openAttachment({
              asrSessionGuid,
              asrCode: this.Id,
              control: true,
              asrTable: masterTableName,
              status: udp.getQueryValue('oType') || OType.Add,
              busTypeCode: this.busType
            });
            this.asrSessionGuid = result.asrSessionGuid;
          }

          render() {
            return (
              <PageContext.Provider value={this.state.providerValue}>
                <PageDetailView />
              </PageContext.Provider>
            );
          }
        }
      }),
    [busType]
  );

  return <InnerPage />;
}

export default function () {
  return <CustomFormDetail />;
}
